#include "Socket.hpp"
#include "Protocol.hpp"
#include <iostream>
#include <string>
#include <memory>

using namespace SocketModule;

void Usage(std::string proc)
{
    std::cerr << "Usage: " << proc << " server_ip server_port" << std::endl;
}

void GetDataFromStdin(int *x, int *y, char *oper)
{
    std::cout << "Please Enter x: ";
    std::cin >> *x;
    std::cout << "Please Enter y: ";
    std::cin >> *y;
    std::cout << "Please Enter oper: ";
    std::cin >> *oper;
}

// ./tcpclient server_ip server_port
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        Usage(argv[0]);
        exit(USAGE_ERR);
    }
    std::string server_ip = argv[1];
    uint16_t server_port = std::stoi(argv[2]);
    std::shared_ptr<Socket> client = std::make_shared<TcpSocket>();
    client->ConnectTcpSocket(server_port, server_ip);

    std::string resp_buffer;
    // 连接服务器成功
    while (true)
    {
        // 1. 从标准输入当中获取数据
        int x, y;
        char oper;
        GetDataFromStdin(&x, &y, &oper);

        // 2. 构建一个请求-> 可以直接发送的字符串
        ProtocolModule::Request req = ProtocolModule::Request(x, y, oper);
        std::string req_str;
        req.Serialize(&req_str);
        LOG(LogLevel::INFO) << "Json string: " << req_str;

        // 3、对请求字符串进行格式加功。
        req_str = ProtocolModule::Encode(req_str);
        LOG(LogLevel::INFO) << "The sentence client will send : " << req_str;
        // std::cout << "-----------encode req string-------------" << std::endl;
        // std::cout << req_str << std::endl;
        // std::cout << "------------------------------------------" << std::endl;

        // 4. 发送请求
        client->WriteMessage(&req_str);

        // 5. 获取应答

        std::string resp_str;
        while (true)
        {
            // _1、读取消息
            bool ret = client->ReadMessage(&resp_str);
            std::cout << "ret : " << ret;
            if (ret)
            {
                std::string IntactMsg;
                // _2、提取消息
                if (ProtocolModule::Decode(resp_str, &IntactMsg))
                {
                    LOG(LogLevel::INFO) << "client receive message form server : (json)" << IntactMsg;
                    // _3、将json串改成结构化数据，成功打印结果退出该层循环，失败输出错误消息
                    ProtocolModule::Response res;
                    if(res.Deserialize(IntactMsg))
                    {
                        res.ShowResponse();
                        break;
                    }
                    else
                    {
                        LOG(LogLevel::WARNING) << "消息反序列化失败！";
                    }
                }
            }
        }

    }
    return 0;
}